#pragma once

#include <functional>

namespace ibox::base {
// 退出区域的时候执行的动作
class ScopeExitActionGuard {
    using ScopeExitFunc = std::function<void()>;

private:
    ScopeExitFunc m_func;

public:
    explicit ScopeExitActionGuard(const ScopeExitFunc &func) : m_func{func} {};
    ~ScopeExitActionGuard() {
        if (m_func) {
            m_func();
        }
    };
    // 禁用复制特性
    ScopeExitActionGuard(const ScopeExitActionGuard &) = delete;
    ScopeExitActionGuard &operator=(const ScopeExitActionGuard &) = delete;
    // 禁用移动特性
    ScopeExitActionGuard(ScopeExitActionGuard &&) = delete;
    ScopeExitActionGuard &operator=(ScopeExitActionGuard &&) = delete;

    void cancel() { m_func = nullptr; };
};
} // namespace ibox::base

// 用途: 使用ScopeExitActionGuard类时, 不用定义一个无意义的变量名.
#define _ScopeExitActionVarName(x)                                             \
    ibox::base::ScopeExitActionGuard _scope_exit_action_guard_##x
#define SetScopeExitAction(...) _ScopeExitActionVarName(__LINE__)(__VA_ARGS__)

/*
示例: 确保离开时自动释放内存, 确保无内存泄漏
Object *obj = new Object();
SetScopeExitAction(
    [=] { delete obj; }
);
*/
